import { Response } from 'express';

/**
 * 分页信息接口
 */
interface PaginationInfo {
  page: number;
  limit: number;
  total: number;
  totalPages: number;
}

/**
 * 统一响应格式工具类
 */
export class ResponseHelper {
  /**
   * 成功响应
   * @param res Express响应对象
   * @param data 响应数据
   * @param message 响应消息
   * @param code HTTP상태码
   */
  static success<T = any>(res: Response, data: T = null as any, message: string = '요청이 성공적으로 처리되었습니다.', code: number = 200): Response {
    return res.status(code).json({
      success: true,
      message,
      data: serializeBigInt(data),
      timestamp: new Date().toISOString()
    });
  }

  /**
   * 错误响应
   * @param res Express响应对象
   * @param message 错误消息
   * @param code HTTP상태码
   * @param error 错误详情（开发环境使用）
   */
  static error(res: Response, message: string = '요청 처리에 실패했습니다.', code: number = 400, error: any = null): Response {
    const response: any = {
      success: false,
      message,
      timestamp: new Date().toISOString()
    };

    // 开发环境返回错误详情
    if (process.env.NODE_ENV === 'development' && error) {
      response.error = error;
    }

    return res.status(code).json(response);
  }

  /**
   * 分页响应
   * @param res Express响应对象
   * @param data 数据列表
   * @param pagination 分页信息
   * @param message 响应消息
   */
  static paginated<T = any>(res: Response, data: T[], pagination: PaginationInfo, message: string = '조회에 성공했습니다.'): Response {
    return res.status(200).json({
      success: true,
      message,
      data: serializeBigInt(data),
      pagination: serializeBigInt(pagination),
      timestamp: new Date().toISOString()
    });
  }

  /**
   * 验证错误响应
   * @param res Express响应对象
   * @param errors 验证错误信息
   */
  static validationError(res: Response, errors: any[] | object): Response {
    return res.status(422).json({
      success: false,
      message: '데이터 검증에 실패했습니다.',
      errors,
      timestamp: new Date().toISOString()
    });
  }

  /**
   * 未授权响应
   * @param res Express响应对象
   * @param message 错误消息
   */
  static unauthorized(res: Response, message: string = '인증되지 않은 접근입니다.'): Response {
    return res.status(401).json({
      success: false,
      message,
      timestamp: new Date().toISOString()
    });
  }

  /**
   * 접근이 금지되었습니다.响应
   * @param res Express响应对象
   * @param message 错误消息
   */
  static forbidden(res: Response, message: string = '접근이 금지되었습니다.'): Response {
    return res.status(403).json({
      success: false,
      message,
      timestamp: new Date().toISOString()
    });
  }

  /**
   * 요청한 리소스를 찾을 수 없습니다.响应
   * @param res Express响应对象
   * @param message 错误消息
   */
  static notFound(res: Response, message: string = '요청한 리소스를 찾을 수 없습니다.'): Response {
    return res.status(404).json({
      success: false,
      message,
      timestamp: new Date().toISOString()
    });
  }

  /**
   * 서버 내부 오류가 발생했습니다.响应
   * @param res Express响应对象
   * @param message 错误消息
   * @param error 错误详情
   */
  static serverError(res: Response, message: string = '서버 내부 오류가 발생했습니다.', error: any = null): Response {
    console.error('서버 오류:', error);
    
    const response: any = {
      success: false,
      message,
      timestamp: new Date().toISOString()
    };

    // 开发环境返回错误详情
    if (process.env.NODE_ENV === 'development' && error) {
      response.error = error.message || error;
      response.stack = error.stack;
    }

    return res.status(500).json(response);
  }
}

/**
 * 简化的API响应工具类（用于返回数据而不是直接响应）
 */
export class ApiResponse {
  /**
   * 成功响应
   * @param data 响应数据
   * @param message 成功消息
   * @param code 상태码
   */
  static success<T>(data: T, message: string = '요청이 성공적으로 처리되었습니다.', code: number = 200) {
    return {
      success: true,
      code,
      message,
      data: serializeBigInt(data),
      timestamp: new Date().toISOString()
    }
  }

  /**
   * 失败响应
   * @param message 错误消息
   * @param code 상태码
   * @param data 附加数据
   */
  static error(message: string = '요청 처리에 실패했습니다.', code: number = 400, data: any = null) {
    return {
      success: false,
      code,
      message,
      data,
      timestamp: new Date().toISOString()
    }
  }
}

/**
 * 处理BigInt序列化工具函数
 * @param obj 需要处理的对象
 * @returns 转换后的对象，所有BigInt都转换为number
 */
export function serializeBigInt(obj: any): any {
  if (obj === null || obj === undefined) {
    return obj;
  }

  if (typeof obj === 'bigint') {
    return Number(obj);
  }

  // 处理Date对象
  if (obj instanceof Date) {
    return obj.toISOString();
  }

  if (Array.isArray(obj)) {
    return obj.map(item => serializeBigInt(item));
  }

  if (typeof obj === 'object') {
    const result: any = {};
    for (const [key, value] of Object.entries(obj)) {
      result[key] = serializeBigInt(value);
    }
    return result;
  }

  return obj;
}

export default ResponseHelper;